/**
 * @file         mfc_com.h
 * @brief        串口对象类
 * @note    
 * @author       Akee
 * @date         2019-9-20
 * @version      1.0
 *
 * @par          修改日志
 * <table>
 * <tr><th>Date        <th>Version               <th>Author          <th>Description
 * <tr><td>2019-9-20   <td>1.0                   <td>Akee            <td>创建初始版本
 * <tr><td>2024-10-22  <td>1.1                   <td>Akee            <td>增加void TMfComSetBaudRateEx( TMfCom *self, Int32 value )接口，Open的时候义NoBlock模式打开
 * @copyright    杭州鸿泉物联网技术股份有限公司
 */
#ifndef _MFC_COM_H_
#define _MFC_COM_H_
#include "ofc/ofc_types.h"
#include "ofc/ofc_object.h"
#include "mfc/mfc_linux.h"

#ifdef __cplusplus
extern "C" {
#endif

/**
 * 串口奇偶校验方式枚举
 */
enum TMfComParityEnumTag
{
    kMfComParityNone,         ///< 无校验 
    kMfComParityOdd,          ///< 奇校验
    kMfComParityEven,         ///< 偶校验
};
typedef enum TMfComParityEnumTag TMfComParityEnum;

/**
 * 串口对象类
 * @par 代码示例
 * @code 
    TMfCom com;

    TMfComCreate(&com);
    TMfComSetName(&com, "/dev/ttyS1");
    TMfComSetBaudRate(&com, 115200);

    if (TMfComOpen(&com))
    {
        ...

        TMfComClose(&com);
    }

    OfDestroyObject((TOfObject *)&com);
 * @endcode
 */
typedef struct TMfComTag TMfCom;
struct TMfComTag
{
    TOfObject parent_;                  ///< 基类

PROTECTED
    TOfVirtualMethod Destroy_;          ///< 析构事件

PRIVATE
    char name_[64];                     ///< 串口名字
    Int32 handle_;                      ///< 串口句柄
    Int32 baud_rate_;                   ///< 串口波特率
    TMfComParityEnum parity_;           ///< 校验方式

    Int32 read_total_timeout_multiplier_; ///< 读取总超时时长,单位:ms
};

/**
 * 串口类构造函数,默认9600的波特率
 * @param self: 对象指针
 * @return 
 */
void TMfComCreate(TMfCom *self);

/**
 * 获取串口的名称; 如: "/dev/ttyS0", "/dev/tty4"
 * @param self: 对象指针
 * @return 串口名称
 */
const char *TMfComName(TMfCom *self);

/**
 * 设置串口名称;
 * @param self: 对象指针
 * @param name: 串口名称,最大只支持63个字节;如: "/dev/ttyS0", "/dev/tty4"
 * @note 必须在串口打开前设置,否则无效
 * @return
 */
void TMfComSetName(TMfCom *self, const char *name);

/**
 * 获取串口波特率
 * @param self: 对象指针
 * @return 波特率
 */
Int32 TMfComBaudRate(TMfCom *self);

/**
 * 设置串口波特率
 * @param self: 对象指针
 * @param value: 设置的波特率; 如: 115200
 * @note 如果已经打开，则实时生效,接口内部直接赋值，并更改底层，如果未打开，则仅赋值
 * @return
 */
void TMfComSetBaudRateEx(TMfCom *self, Int32 value);

/**
 * 设置串口波特率
 * @param self: 对象指针
 * @param value: 设置的波特率; 如: 115200
 * @note 必须在串口打开前设置,否则无效,接口内部直接赋值
 * @return
 */
void TMfComSetBaudRate(TMfCom *self, Int32 value);

/**
 * 获取串口的数据校验方式
 * @param self: 对象指针
 * @return 校验方式
 */
TMfComParityEnum TMfComParity(TMfCom *self);

/**
 * 设置串口的校验方式
 * @param self: 对象指针
 * @param value: 校验方式
 * @note 必须在串口打开前设置,否则无效
 * @return
 */
void TMfComSetParity(TMfCom *self, TMfComParityEnum value);

/**
 * 读取总时长超时时间,时长 = ReadTotalTimeoutMultiplier / 100 * 100 ms;
 * @param self: 对象指针
 * @return 时长,单位:ms
 */
Int32 TMfComReadTotalTimeoutMultiplier(TMfCom *self);

/**
 * 设置读取总超时时长.
 * @param self: 对象指针
 * @param ms: 时长,单位ms; 注：该时长会作调整,ms / 100 * 100.比如输入190ms,实际是100ms
 * @note 必须在串口打开前设置,否则无效
 * @return
 */
void TMfComSetReadTotalTimeoutMultiplier(TMfCom *self, Int32 ms);

/**
 * 串口句柄
 * @param self: 对象指针
 * @return 句柄
 */
Int32 TMfComHandle(TMfCom *self);

/**
 * 打开串口; 注: 波特率和奇偶校验信息,以及读取时长必须在Open前设置
 * @param self: 对象指针
 * @return True: 成功; False: 失败
 */
Bool TMfComOpen(TMfCom *self);

/**
 * 关闭串口
 * @param self: 对象指针
 * @return
 */
void TMfComClose(TMfCom *self);

/**
 * 从串口读取数据
 * @param self: 对象指针
 * @param buf: 读取数据的缓冲区
 * @param size: 最大读取的数据数
 * @return 实际读取的字节数,参数错误时为-1
 * @note 需要在Open成功后使用，内部不判断句柄的有效性
 */
Int32 TMfComRead(TMfCom *self, void *buf, Int32 size);

/**
 * 写数据到串口
 * @param self: 对象指针
 * @param data: 写入数据的缓冲区
 * @param data_size: 写入的字节数
 * @return 实际写入的字节数,参数错误时为-1
 * @note 需要在Open成功后使用，内部不判断句柄的有效性
 */
Int32 TMfComWrite(TMfCom *self, const void *data, Int32 data_size);

/**
 * 写一个字符串到串口
 * @param self: 对象指针
 * @param str: 需要写入的字符串
 * @return 实际写入的字节数,参数错误时为-1
 * @note 需要在Open成功后使用，内部不判断句柄的有效性
 */
Int32 TMfComWriteString(TMfCom *self, const char *str);

/**
 * 清除串口缓冲区的内容
 * @param self: 对象指针
 * @return
 */
void TMfComClear(TMfCom *self);

/**
 * 返回串口是否已经打开
 * @param self: 对象指针
 * @return True: 已打开; False: 未打开
 */
Bool TMfComIsOpen(TMfCom *self);


#ifdef __cplusplus
}
#endif
#endif
